package com.carbon.auth.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.carbon.auth.entity.SysAccount;
import com.carbon.auth.mapper.LoginMapper;
import com.carbon.auth.service.LoginService;
import com.carbon.auth.service.SmsService;
import com.carbon.common.exception.CommonBizException;
import com.carbon.common.utils.HttpContextUtils;
import com.carbon.domain.auth.param.ForgotPasswordParam;
import com.carbon.domain.auth.param.LoginParam;
import com.carbon.domain.auth.param.RegisterParam;
import com.carbon.domain.auth.vo.LoginInfoVo;
import com.carbon.domain.auth.vo.SecurityData;
import com.carbon.domain.common.ApiCode;
import com.carbon.domain.common.ApiResult;
import com.carbon.domain.common.constant.RedisKeyName;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;


/**
 * <p>
 * 帐号  前端控制器
 * </p>
 *
 * @author Li Jun
 * @since 2021-06-11
 */
@Slf4j
@RestController
@RequestMapping("/auth")
@Api(value = "登录 模块", tags = {"登录 模块"})
public class LoginController {
    @Resource
    LoginMapper loginMapper;

    @Autowired
    private LoginService loginService;
    @Autowired
    private SmsService smsService;


    @PostMapping("/register")
    @ApiOperation(value = "注册", notes = "注册", response = ApiResult.class)
    public ApiResult register(@Validated @RequestBody RegisterParam param) {
        LambdaQueryWrapper<SysAccount> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysAccount::getAccountName, param.getAccountName())
                .or().eq(SysAccount::getPhone, param.getPhone());
        int count = loginMapper.selectCount(queryWrapper);
        if (count > 0) {
            return ApiResult.<SysAccount>ok(ApiCode.ACCOUNT_DUPLICATE,"重复",null);
        }
        try {
            loginService.register(param);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        return ApiResult.ok("注册成功");
    }


//@PostMapping("/register")
//@ApiOperation(value = "注册", notes = "注册（需校验手机号验证码）", response = ApiResult.class)
//public ApiResult register(@Validated @RequestBody RegisterParam param) {
//     smsService.checkValidateCode(param.getPhone(), param.getCode(), RedisKeyName.SMS_REGISTER_KEY);
//
//    // 2. 原逻辑：校验用户名/手机号是否已存在
//    LambdaQueryWrapper<SysAccount> queryWrapper = new LambdaQueryWrapper<>();
//    queryWrapper.eq(SysAccount::getAccountName, param.getAccountName())
//            .or().eq(SysAccount::getPhone, param.getPhone());
//    int count = loginMapper.selectCount(queryWrapper);
//    if (count > 0) {
//        // 注意：ApiCode.ACCOUNT_DUPLICATE建议返回400错误码，而非200
//        return ApiResult.<SysAccount>fail(ApiCode.ACCOUNT_DUPLICATE, "用户名或手机号已存在");
//    }
//
//    // 3. 执行注册逻辑
//    try {
//        loginService.register(param);
//    } catch (NoSuchAlgorithmException e) {
//        log.error("注册加密异常", e);
//        throw new CommonBizException("注册失败，请稍后重试");
//    }
//
//    return ApiResult.ok("注册成功");
//}

    @PostMapping("/login")
    @ApiOperation(value = "登录", notes = "登录", response = ApiResult.class)
    public ApiResult login(@Validated @RequestBody LoginParam loginParam, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
        LoginInfoVo loginInfoVo = loginService.byLoginName(loginParam);
        String accountName = StrUtil.trimToEmpty(loginParam.getAccountName());
        SysAccount account = loginMapper.selectOne(Wrappers.lambdaQuery(SysAccount.class).eq(SysAccount::getAccountName, accountName));
        LambdaQueryWrapper<SecurityData> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SecurityData::getTenantId, loginInfoVo.getSecurityData().getTenantId());
        String jsonStr = JSON.toJSONString(account.getId());
        // 2. 对 JSON 字符串进行 URL 编码（避免特殊字符）
        String encodedValue = java.net.URLEncoder.encode(jsonStr, StandardCharsets.UTF_8.name());
        Cookie cookie = new Cookie("JavaInfo",encodedValue);
        cookie.setPath("/"); // 关键：设置为根路径，全站可访问
        cookie.setDomain("localhost");
        cookie.setMaxAge(3600 * 24); // 有效期（秒），24小时
        response.addCookie(cookie);
        return ApiResult.result(200,"登录成功",loginInfoVo);
    }

    @GetMapping("/logout")
    @ApiOperation(value = "退出登录", notes = "退出登录")
    public ApiResult<Boolean> logout() {
        loginService.logout(HttpContextUtils.getAccountId());
        return ApiResult.ok();
    }


    @GetMapping("/register/code/{phone}")
    @ApiOperation(value = "验证码-注册", notes = "获取注册验证码")
    public ApiResult<Boolean> sendRegisterCode(@PathVariable String phone) {
        smsService.sendRegisterCode(phone);
        return ApiResult.ok();
    }


    @GetMapping("/forgotPassword/code/{phone}")
    @ApiOperation(value = "验证码-忘记密码", notes = "获取验证码")
    public ApiResult<Boolean> sendForgotPasswordCode(@PathVariable String phone) {
        smsService.sendForgotPasswordCode(phone);
        return ApiResult.ok();
    }

    @PostMapping("/forgotPassword")
    @ApiOperation(value = "忘记密码", notes = "忘记密码，找回密码", response = ApiResult.class)
    public ApiResult forgotPassword(@Validated @RequestBody ForgotPasswordParam param) {
        loginService.forgotPassword(param);
        return ApiResult.ok();
    }

    @GetMapping("/verify/{accountName}")
    @ApiOperation(value = "验证账户是否存在", notes = "验证账户是否存在,存在返回false")
    public ApiResult<Boolean> verifyAccountName(@PathVariable String accountName) {
        return ApiResult.ok();
        //return ApiResult.ok(loginService.verify(accountName));
    }
}

